package app

import (
	"net/http"
	"strings"
)

type service interface {
	//绑定路由与控制器
	BindController(path string, controller func(http.ResponseWriter, *http.Request))
	//到控制器前的一些处理
	Guard(middlewareStr string) httpService
	//服务地址
	Address(address string) httpService
	//服务端口
	Port(port string) httpService
	//开始监听http服务
	Run()
	//注册守卫
	CallGuard(name string) httpService
	//守卫的检查
	Action(call func(r *http.Request, path string)) httpService
	//守卫的断后工作
	CoverRetreat(call_defer func(r *http.Request, path string))
}

func init() {
	//默认
	Service = httpService{_address: "127.0.0.1", _port: "8080"}
	MiddlewareMapping = make(map[string]*middleware)
}

var MiddlewareMapping map[string]*middleware

var GuardName string

func (this httpService) CallGuard(name string) httpService {
	GuardName = name
	return this
}

func (this httpService) Action(call func(r *http.Request, path string)) httpService {
	MiddlewareMapping[GuardName] = &middleware{call: call}
	if _, is_exist := MiddlewareMapping[GuardName]; !is_exist {
		MiddlewareMapping[GuardName] = &middleware{call: call}
	} else {
		MiddlewareMapping[GuardName].call = call
	}
	return this
}

func (this httpService) CoverRetreat(call_defer func(r *http.Request, path string)) {
	if _, is_exist := MiddlewareMapping[GuardName]; is_exist {
		MiddlewareMapping[GuardName].call_defer = call_defer
	} else {
		MiddlewareMapping[GuardName] = &middleware{call_defer: call_defer}
	}
}

type middleware struct {
	call       func(r *http.Request, path string)
	call_defer func(r *http.Request, path string)
}

var Service service

type httpService struct {
	_address     string
	_port        string
	_middlewares []string
}

func (this httpService) BindController(path string, controller func(http.ResponseWriter, *http.Request)) {
	http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
		for _, middleware := range this._middlewares {
			if _, isExist := MiddlewareMapping[middleware]; !isExist {
				continue
			}
			if MiddlewareMapping[middleware].call != nil {
				MiddlewareMapping[middleware].call(r, path)
			}
			if MiddlewareMapping[middleware].call_defer != nil {
				defer MiddlewareMapping[middleware].call_defer(r, path)
			}
			// 	defer Exception.Listen(w, path)
		}
		controller(w, r)
	})
}

func isFunc(i interface{}) bool {
	switch i.(type) {
	case func(r *http.Request, path string):
		return true
	case int:
	case bool:
	default:
		return false
	}
	return false
}

func (this httpService) Guard(middlewareName string) httpService {
	this._middlewares = strings.Split(middlewareName, "|")
	return this
}

func (this httpService) Address(address string) httpService {
	this._address = address
	return this
}

func (this httpService) Port(port string) httpService {
	this._port = port
	return this
}

func (this httpService) Run() {
	http.ListenAndServe(this._address+":"+this._port, nil)
}
